package com.zhang.util;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;

@Component
@Aspect //表明是织入类
public class ServiceUtil {
    private static SqlSessionFactory sqlSessionFactory;

    static {
        try {
            InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Around("execution(* com.zhang.service..*.*(..))")//这是跟service接口实现类联系的地方，才能进行织入
    public Object proxyService(ProceedingJoinPoint point){
        //得到sqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //获取目标对象
        Object target = point.getTarget();
        //获取目标对象的类模板
        Class targetClass = target.getClass();
        //获取目标对象的属性列表
        Field[] fields = targetClass.getDeclaredFields();

        Object returnObj = null;

        for (Field f: fields) {
            //扯开私有属性的验证
            f.setAccessible(true);
            if (f.getType().isInterface()){
                Object mapper = sqlSession.getMapper(f.getType());
                try {
                    f.set(target,mapper);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }

        try {
            returnObj = point.proceed();
            sqlSession.commit();
        } catch (Throwable throwable) {
            sqlSession.rollback();
            throwable.printStackTrace();
        }finally {
            sqlSession.close();
        }


        return returnObj;
    }

}
